import os
import sys
import json
import socket

from src.settings import Settings


class UserDataLoader:
    a_week = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

    def __init__(self, ini_dict: dict):
        # 参数传递
        self.version = ini_dict["程序版本"]
        self.__exe_cmd = str(ini_dict["开服命令"])
        self.exe_stop_cmd = ini_dict.get("关服命令", "stop")
        self.exe_stop_wait = ini_dict.get("关服时限", 6)
        self.exe_re_alive = ini_dict["崩溃重启"]
        self.exe_re_alive_limit = ini_dict.get("连续崩溃时限", 180)
        self.server_port = ini_dict.get("服务端口")
        self.server_token = ini_dict.get("服务token", "")
        self.exe_bak = ini_dict["自动备份"]
        self.re_bak_day = [self.a_week[i - 1] for i in ini_dict["周备份日"]]
        self.re_bak_time = [str(t).replace(":", "").replace("：", "") + "00" for t in ini_dict["备份时间"]]
        self.world_dirs = ini_dict["存档路径"]
        self.bak_dir = str(ini_dict["保存位置"])
        self.bak_name = str(ini_dict["保存文件名"])
        self.bak_limit_num: int = ini_dict.get("备份保留数量", -1)
        self.bak_seven_zip = ini_dict.get("7z压缩", False)
        self.output_shield = ini_dict["输出屏蔽"]
        self.robot_on = ini_dict["启用机器人"]
        # 解析域名获取ip地址
        self.robot_host = socket.gethostbyname(ini_dict["机器人地址"])
        self.robot_port = ini_dict["机器人端口"]
        self.robot_key = str(ini_dict["access-token"])
        self.robot_owner = ini_dict["管理员QQ号"]
        self.robot_group = ini_dict["管理QQ群号"]
        self.robot_re_list = ini_dict["正则匹配"]
        self.robot_group_cmd = ini_dict["群自定义命令"]
        # windows中分割路径切换目录
        if Settings.OS_PLATFORM == 'Windows':
            self.exe_dir, self.exe_name = os.path.split(self.__exe_cmd)
        elif Settings.OS_PLATFORM == 'Darwin':  # Darwin(macOS)
            self.exe_dir = "."
            self.exe_name = 'open ' + self.__exe_cmd
        else:  # linux中路径分割存在问题
            self.exe_dir = "."
            self.exe_name = self.__exe_cmd
        # 参数检查
        self.__check()

    # 加__表示私有成员
    def __check(self) -> None:
        # 读取版本
        if self.version not in Settings.COMPATIBLE_VERSIONS:
            input("[GLF机器人][WARN] 配置文件版本过低，请使用新版再运行本程序")
            sys.exit()
        # 存档路径自动转换
        if type(self.world_dirs) == str:
            self.world_dirs = [self.world_dirs]
        # 输出屏蔽异常处理
        if type(self.output_shield) != list:
            self.output_shield = []
            print("[GLF机器人][WARN] 输出屏蔽格式异常！此功能将被禁用")
        if type(self.robot_re_list) != list:
            self.robot_re_list = []
            print("[GLF机器人][WARN] 正则匹配格式异常！此功能将被禁用")
        if type(self.robot_group_cmd) != list:
            self.robot_group_cmd = []
            print("[GLF机器人][WARN] 群消息匹配格式异常！此功能将被禁用")


class UserData:
    def __init__(self):
        self.__ini_dir = Settings.WORK_PATH + "/DLS/"
        self.__ini_files = ["配置.json", "备份.json", "机器人配置.json",
                            "机器人正则.json", "机器人命令.json"]
        self.__data_dir = Settings.WORK_PATH + "/DLS/数据/"
        self.__data_files = ["命令次数记录.json"]
        self.iniCls: UserDataLoader
        self.dataDict = {}
        self.is_load = False
        self.reload()

    # 重加载所有配置
    def reload(self) -> None:
        self.loadSettings()
        self.loadData()
        print("[GLF机器人] 配置文件加载完成！")

    # 加载配置文件并合并字典
    def loadSettings(self) -> None:
        ini_dict = {}
        for file in self.__ini_files:
            content = self.loadJson(self.__ini_dir + file)
            if type(content) == dict:
                ini_dict.update(content)
            else:
                print(f"[GLF机器人][ERROR] 加载配置文件{self.__ini_dir + file}失败！")
        try:
            if not ini_dict:
                print("[GLF机器人][ERROR] 未找到任何配置文件，配置文件可能丢失")
                print("[GLF机器人][ERROR] 或尝试先切换到DLS所在目录，再运行此程序")
                input("[GLF机器人][ERROR] 程序终止，按下Enter键退出...")
                sys.exit()
            self.iniCls = UserDataLoader(ini_dict)
            self.is_load = True
        except Exception as err:
            if self.is_load:
                print(f"[GLF机器人][ERROR] 加载配置文件出现错误: {err}")
                print("[GLF机器人][ERROR] 所有配置将会回滚...")
            else:
                print(f"[GLF机器人][ERROR] 配置文件初始加载出现错误: {err}")
                input("[GLF机器人][ERROR] 程序终止，按下Enter键退出...")
                sys.exit()

    # 加载数据文件并合并字典
    def loadData(self) -> None:
        self.dataDict = {}
        if not os.path.exists(self.__data_dir):
            os.mkdir(self.__data_dir)
        for file in self.__data_files:
            content = self.loadJson(self.__data_dir + file)
            if type(content) == dict:
                self.dataDict.update(content)
            else:
                print(f"[GLF机器人][ERROR] 加载数据文件{self.__ini_dir + file}失败！")

    # 从文件加载json
    @staticmethod
    def loadJson(file_name: str):
        if os.path.exists(file_name):
            try:
                with open(file_name, "rb") as f:
                    return json.loads(f.read())
            except json.decoder.JSONDecodeError:
                print("[GLF机器人][ERROR] 配置文件json格式有误，请检查格式")
            except UnicodeDecodeError:
                print("[GLF机器人][ERROR] 配置文件编码被更改，不支持的编码格式")
            except Exception as err:
                print(f"[GLF机器人][ERROR] {err}")
                return
        else:
            return {}
